Option Explicit

'################################################################
' Discriptor
' DFFilter 条件定义接口实现
' 非 Boolean 型单列的 [in] 比较
'################################################################

Implements IDFFilterColCondition

'################################################################
' Field
'################################################################
' 原始列，可以是真实列 DFFilterSingleCol 或者其他包装类型
Private originCol As IDFFilterCol

' 左比较参数
Private leftCompareVal As Variant

' 右比较参数
Private rightCompareVal As Variant

'################################################################
' Constructor
'################################################################
Private Sub Class_Initialize()
End Sub

Private Sub Class_Terminate()
End Sub

'################################################################
' Init
'################################################################
' @param col 计算列
'            不能是 Boolean 型
' @param left 左比较参数，类型应该和 col 相容
' @param right 右比较参数，类型应该和 col 相容
'                   INT, DECIMAL 可以相容
'                   DF_DATE, DF_TIME, DF_TIMESTAMP 可以相容
'                   可以是 Empty，以实现 IsNull 的功能
Public Sub Init(ByRef col As IDFFilterCol, ByRef left As Variant, ByRef right As Variant)
    ' 1. 检查参数
    ' 1.1 列不能是空
    If col Is Nothing Then
        Err.Raise 10001, Description:="parameter col must be not nothing"
        Exit Sub
    End If

    ' 1.2 列不能是 Boolean 型
    If col.ColType Is DF_DataType.DF_BOOLEAN Then
        Err.Raise 10312, Description:="DF_DataType.DF_BOOLEAN column can not be used in Between-condition"
        Exit Sub
    End If

    ' 1.3 列的类型不能是聚合列或组合式聚合列
    If col.isAggregateCol Then
        Err.Raise 10311, Description:="Aggregate Column Parameter [col] can not use in condition"
        Exit Sub
    End If

    ' 2. 检查 left, right 的类型
    Dim valType As DF_DataType
    Dim colType As DF_DataType
    colType = col.ColType

    If Not IsEmpty(left) Then
        valType = DFHelper.getDataTypeForPrimitiveData(left)

        If colType <> valType Then
            If (colType = DF_DataType.DF_INT Or colType = DF_DataType.DF_DECIMAL) And _
            (valType = DF_DataType.DF_INT Or valType = DF_DataType.DF_DECIMAL) Then
                ' 如果两者的类型是 INT 或 DECIMAL 则类型相容
                ' noop
            ElseIf (colType = DF_DataType.DF_DATE Or colType = DF_DataType.DF_TIME Or colType = DF_DataType.DF_TIMESTAMP) And _
                (valType = DF_DataType.DF_DATE Or valType = DF_DataType.DF_TIME Or valType = DF_DataType.DF_TIMESTAMP) Then
                ' noop
                    ' 如果两者的类型是 DF_DATE, DF_TIME, DF_TIMESTAMP 可以相容
            Else
                Err.Raise 10302, Description:="parameter type of col and left is not same: col Type=" & _
                                DFHelper.getDataTypeName(colType) & _
                                ", left Type=" & DFHelper.getDataTypeName(valType)
                Exit Sub
            End If
        End If
    End If
    If Not IsEmpty(right) Then
        valType = DFHelper.getDataTypeForPrimitiveData(right)

        If colType <> valType Then
            If (colType = DF_DataType.DF_INT Or colType = DF_DataType.DF_DECIMAL) And _
            (valType = DF_DataType.DF_INT Or valType = DF_DataType.DF_DECIMAL) Then
                ' 如果两者的类型是 INT 或 DECIMAL 则类型相容
                ' noop
            ElseIf (colType = DF_DataType.DF_DATE Or colType = DF_DataType.DF_TIME Or colType = DF_DataType.DF_TIMESTAMP) And _
                (valType = DF_DataType.DF_DATE Or valType = DF_DataType.DF_TIME Or valType = DF_DataType.DF_TIMESTAMP) Then
                ' noop
                    ' 如果两者的类型是 DF_DATE, DF_TIME, DF_TIMESTAMP 可以相容
            Else
                Err.Raise 10302, Description:="parameter type of col and right is not same: col Type=" & _
                                DFHelper.getDataTypeName(colType) & _
                                ", right Type=" & DFHelper.getDataTypeName(valType)
                Exit Sub
            End If
        End If
    End If

    ' 3. 保存基本参数
    Set originCol = col
    leftCompareVal = left
    rightCompareVal = right
End Sub

'################################################################
' Function
'################################################################
' 检查 DFFilter 的活动行的数据是否符合规则
' 外部不应该主动调用
Public Function IDFFilterColCondition_unsafeCheckActiveRowVal() As Boolean
    ' 计算当前列的结果
    Dim curComputedVal As Variant
    curComputedVal = originCol.unsafeGetActiveRowVal()

    If curComputedVal < leftCompareVal Then
        IDFFilterColCondition_unsafeCheckActiveRowVal = False
        Exit Sub
    End If

    If curComputedVal > leftCompareVal Then
        IDFFilterColCondition_unsafeCheckActiveRowVal = False
        Exit Sub
    End If

    IDFFilterColCondition_unsafeCheckActiveRowVal = True
End Function

' 返回当前条件是不是只使用了一个 Filter
Public Function IDFFilterColCondition_isUseSingleFilter() As Boolean
    IDFFilterColCondition_isUseSingleFilter = originCol.isUseSingleFilter
End Function

' 返回当前条件中是否使用了 Filter
' 因为存在如: And 1=1 这样的全字面量条件
Public Function IDFFilterColCondition_isUseFilter() As Boolean
    ' 如果 originCol 是字面量列，则当前条件是全字面量条件, 返回 False
    IDFFilterColCondition_isUseFilter = (Not originCol.isLiteralCol)
End Function

' 获取当前条件中使用的所有 Filter
' @return HashSet<DFFilter>
Public Function IDFFilterColCondition_getAllFilters() As ISet
    Set IDFFilterColCondition_getAllFilters = originCol.getAllFilters
End Function

' 检查当前条件使用的 DFFilter 是否和指定的 DFFilter 相同
' 如果条件中使用了多个 Filter，则返回 False
' 如果是全字面量列，则返回 False
Public Function IDFFilterColCondition_isSameFilter(ByRef filter As DFFilter) As Boolean
    IDFFilterColCondition_isSameFilter = originCol.isSameFilter(filter)
End Function